//
//  KATBrowserConfig.m
//  KATFramework
//
//  Created by Yi Yu on 2017/6/22.
//  Copyright © 2017年 KatApp. All rights reserved.
//

#import "KATBrowserConfig.h"



@interface KATBrowserConfig ()

#pragma -mark 属性

///控制器
@property(nonatomic,retain) WKUserContentController *controller;

///WebView的配置
@property(nonatomic,retain) WKWebViewConfiguration *webConfig;

///selector名称Map
@property(nonatomic,retain) KATHashMap<NSString *> *selectorMap;

///方法调用者Map
@property(nonatomic,retain) KATHashMap<id> *handlerMap;


@end




@implementation KATBrowserConfig


#pragma -mark 类方法

//获取实例
+ (instancetype)config
{
    return [[[self alloc] init] autorelease];
}


//初始化
- (instancetype)init
{
    self=[super init];
    
    self.schemes=ARRAY(@"sms",@"telprompt",@"mailto",@"itms-apps");
    self.hostsFilter=nil;
    self.marginTop=0.0;
    self.marginBottom=0.0;
    self.marginLeft=0.0;
    self.marginRight=0.0;
    self.topInsertHeight=0.0;
    self.bottomInsertHeight=0.0;
    self.bottomView=nil;
    
    //弹窗
    self.alertWindow=[KATAlertWindow windowWithTitle:nil];
    self.confirmWindow=[KATButtonWindow windowWithTitle:nil titleStyle:nil info:nil infoStyle:nil andButtons:ARRAY([KATButton buttonWithFrame:CGRectZero type:KATButtonTypeClose color:KCOLOR_RED lineWidth:1.5 scale:1.0 andOnClickAction:nil],[KATButton buttonWithFrame:CGRectZero type:KATButtonTypeOK color:KCOLOR_BLUE lineWidth:1.5 scale:1.0 andOnClickAction:nil])];
    self.inputWindow=[KATInputWindow windowWithTitle:nil];
    
    //进度条
    self.progressBar=[KATProgressBar progressBarWithFrame:CGRectMake(0, 0, 0, 2.0)];
    self.progressBar.hasRoundCorner=NO;
    self.progressBar.frontIndent=0;
    self.progressBar.color=COLOR_BLUE;
    self.progressBar.bgColorAlpha=0.0;
    [self.progressBar updateBar];
    
    self.controller=[[[WKUserContentController alloc] init] autorelease];
    self.webConfig=[[[WKWebViewConfiguration alloc] init] autorelease];
    self.webConfig.allowsInlineMediaPlayback=YES;
    
    if([OS_VERSION doubleValue]>=9.0)
    {
        self.webConfig.allowsAirPlayForMediaPlayback=YES;
    }
    
    self.webConfig.userContentController=self.controller;
    
    self.selectorMap=[KATHashMap hashMap];
    self.handlerMap=[KATHashMap hashMap];
    
    return self;
}


//清空缓存
+ (void)clearCache
{
    //清除WebView的缓存
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
}


//清空cookie
+ (void)clearCookies
{
    //清除cookies
    NSHTTPCookie *cookie;
    
    NSHTTPCookieStorage *storage=[NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    for(cookie in [storage cookies])
    {
        [storage deleteCookie:cookie];
    }
}

#pragma -mark 对象方法

//注入js脚本
- (void)addScript:(WKUserScript *)script
{
    if(_controller)
    {
        [_controller addUserScript:script];
    }
}


//注入js脚本字符串(只限主窗口，且添加在文件末尾)
- (void)addJS:(NSString *)js
{
    if(js)
    {
        WKUserScript *script=[[[WKUserScript alloc] initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES] autorelease];// forMainFrameOnly:NO(全局窗口)，yes（只限主窗口）
        
        [self addScript:script];
    }
}


//清除注入的JS脚本
- (void)clearScripts
{
    if(_controller)
    {
        [_controller removeAllUserScripts];
    }
}


//添加本地方法的JS映射，在JS代码中用window.webkit.messageHandlers.<method>.postMessage(<messageBody>)调用(省略<>)，只能带一个参数，可以封装成Map
- (void)addJSMethod:(NSString *)method withSelector:(SEL)sel forHandler:(id)handler
{
    if(method && sel && handler)
    {
        if(_controller)
        {
            if(!_handlerMap[method])//未添加过的方法名，不能重复添加
            {
                //保存到map
                _selectorMap[method]=NSStringFromSelector(sel);
                _handlerMap[method]=handler;
                
                //添加(强引用，释放前需要删除)
                [_controller addScriptMessageHandler:self name:method];
            }
        }
    }
}


//删除本地方法的JS映射
- (void)removeJSMethod:(NSString *)method
{
    if(method)
    {
        //从Map中删除
        [_selectorMap deleteValueWithKey:method];
        [_handlerMap deleteValueWithKey:method];
        
        if(_controller)
        {
            //删除
            [_controller removeScriptMessageHandlerForName:method];
        }
    }
}


//清除所有的本地方法JS映射(清除后才能完全释放内存)
- (void)clearJSMethods
{
    KATArray *methods=[_handlerMap allKeys];
    
    //逐个删除
    for(NSString *method in methods)
    {
        [_controller removeScriptMessageHandlerForName:method];
    }
    
    //清除Map
    [_selectorMap clear];
    [_handlerMap clear];
}


//禁用用户选择事件
- (void)disableUserSelectEvent
{
    [self addJS:@"document.documentElement.style.webkitUserSelect='none';"];
}


//禁用用户长按事件
- (void)disableUserPressEvent
{
    [self addJS:@"document.documentElement.style.webkitTouchCallout='none';"];
}



#pragma -mark WKScriptMessageHandler代理

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    //获取JS的方法名和参数
    NSString *method=message.name;
    id value=message.body;
    
    //本地方法名和调用者
    NSString *selector=_selectorMap[method];
    id handler=_handlerMap[method];
    
    if(selector && handler)
    {
        SEL sel=NSSelectorFromString(selector);
        
        if([handler respondsToSelector:sel])
        {
            [handler performSelector:sel withObject:value];
        }
    }
}


//释放内存
- (void)dealloc
{    
    //清除JS方法
    [self clearJSMethods];
    
    [_alertWindow release];
    [_confirmWindow release];
    [_inputWindow release];
    [_bottomView release];
    [_schemes release];
    [_hostsFilter release];
    [_progressBar release];
    [_controller release];
    [_webConfig release];
    [_selectorMap release];
    [_handlerMap release];
    
    [super dealloc];
}


@end
